﻿using Magic.Core;
using SqlSugar;

namespace Magic.System;

[Injection]
public class AuthService : IAuthService
{
    private readonly ISysUserRoleService _sysUserRoleService;
    private readonly ISysRoleService _sysRoleService;
    private readonly IMenuService _menuService;
    private readonly IConfigService _configService;
    private readonly IJWTBuilder _jwtBuilder;
    private readonly IEventPublisher _eventPublisher;
    public AuthService(
        ISysUserRoleService sysUserRoleService,
        ISysRoleService sysRoleService,
        IMenuService menuService,
        IConfigService configService,
        IJWTBuilder jwtBuilder,
        IEventPublisher eventPublisher)
    {
        _sysUserRoleService = sysUserRoleService;
        _sysRoleService = sysRoleService;
        _menuService = menuService;
        _configService = configService;
        _jwtBuilder = jwtBuilder;
        _eventPublisher = eventPublisher;
    }
    /// <summary>
    /// 获取登录用户信息
    /// </summary>
    /// <returns></returns>
    public async Task<LoginUserInfoOutput> GetLoginUserInfo()
    {
        var user = await SugarContext.Instance
            .Queryable<SysUser>()
            .Where(m => m.Id == UserManager.UserId)
            .Select<UserInfoOutput>()
            .FirstAsync();
        var userRole = await _sysUserRoleService.GetListByUserId(user.Id);
        var menuIds = await _sysRoleService.GetPermissionsByIds(userRole.Select(m => m.RoleId).ToList());
        var menuTree = await _menuService.GetTree(menuIds.Contains("*") ? null : menuIds.SplitToIntList().ToList());

        LoginUserInfoOutput result = new LoginUserInfoOutput
        {
            AdminInfo = user,
            Menus = menuTree,
            SiteConfig = new
            {
                ApiUrl = "https://buildadmin.com",
                CdnUrl = "https://localhost:5001",
                SiteName = await _configService.GetByName("site_name"),
                Upload = new
                {
                    maxsize = 10485760,
                    mimetype = await _configService.GetByName("file_mimetype"),
                    mode = await _configService.GetByName("file_mode"),
                    savename = await _configService.GetByName("file_name_format")
                },
                Version = await _configService.GetByName("version")
            }
        };
        return result;
    }
    /// <summary>
    /// 用户登录
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<LoginOutput> Login(LoginInput input)
    {
        string pwd = MD5Encryption.Encrypt(input.Password);
        var user = await SugarContext.Instance.Queryable<SysUser>().FirstAsync(m => m.Username == input.UserName && m.Password == pwd);
        if (user == null)
        {
            throw new ApiException("用户名或密码错误");
        }
        var userRole = await SugarContext.Instance.Queryable<SysUserRole, SysRole>((aga, ag)
            => new JoinQueryInfos(JoinType.Inner, aga.RoleId == ag.Id))
            .Where((aga, ag) => aga.Uid == user.Id)
            .Select((aga, ag) => ag.Name)
            .ToListAsync();
        //判断是否超级管理员
        var IsSuperAdmin = userRole.Contains("超级管理组") ? AccountTypeEnum.SuperAdmin : AccountTypeEnum.User;


        //生成Token
        string accessToken = _jwtBuilder.CreateToken(new Dictionary<string, object> {
             {
                ClaimConst.UserId, user.Id
            },
            {
                ClaimConst.UserName, user.Username
            },
            {
                ClaimConst.NickName, user.Nickname
            },
            {
                ClaimConst.AccountType,IsSuperAdmin
            }
        });

        //登录事件
        await _eventPublisher.PublishAsync(new ChannelEventSource(EventConst.LoginCallBack, new EventLoginCallBackDto
        {
            Lastlogintime = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds(),
            Lastloginip = HttpUtil.GetRemoteIp(),
            UserId = user.Id
        }));

        //返回结果
        return new LoginOutput
        {
            RoutePath = "/admin",
            UserInfo = new UserInfoOutput
            {
                Id = user.Id,
                Username = user.Username,
                Nickname = user.Nickname,
                Lastlogintime = user.Lastlogintime,
                Avatar = user.Avatar,
                Token = accessToken,
                RefreshToken = ""
            }
        };
    }
    /// <summary>
    /// 退出登录
    /// </summary>
    /// <returns></returns>
    public async Task Logout()
    {
        await Task.Run(() =>
        {

        });
    }
}
